package com.zhonghui.wms.service.impl;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import com.zhonghui.common.utils.DateUtils;
import com.zhonghui.common.utils.SecurityUtils;
import com.zhonghui.mes.domain.MesProductionCompletion;
import com.zhonghui.mes.domain.vo.MesProductionCompletionVo;
import com.zhonghui.mes.mapper.MesProductionCompletionMapper;
import com.zhonghui.mes.service.IMesProductionCompletionService;
import com.zhonghui.scm.domain.ScmPurchaseArrival;
import com.zhonghui.scm.domain.ScmSaleReturn;
import com.zhonghui.scm.mapper.ScmPurchaseArrivalMapper;
import com.zhonghui.scm.mapper.ScmSaleReturnMapper;
import com.zhonghui.scm.service.IScmPurchaseArrivalService;
import com.zhonghui.scm.service.IScmPurchaseReturnService;
import com.zhonghui.scm.service.IScmSaleReturnService;
import com.zhonghui.wms.domain.*;
import com.zhonghui.wms.domain.vo.WmsInventoryDetailsVo;
import com.zhonghui.wms.domain.vo.WmsMaterialInventoryVo;
import com.zhonghui.wms.domain.vo.WmsWarehousingApplicationVo;
import com.zhonghui.wms.mapper.*;
import com.zhonghui.wms.service.IWmsMaterialInventoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import com.zhonghui.common.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import com.zhonghui.wms.service.IWmsWarehousingApplicationService;

/**
 * 智能仓储WMS-入库申请Service业务层处理
 *
 * @author zhonghui
 * @date 2022-05-25
 */
@Service
public class WmsWarehousingApplicationServiceImpl implements IWmsWarehousingApplicationService
{
    @Autowired
    private WmsWarehousingApplicationMapper wmsWarehousingApplicationMapper;

    @Autowired
    private WmsWarehousingApplicationDetailsMapper wmsWarehousingApplicationDetailsMapper;

    @Autowired
    private WmsWarehouseMapper wmsWarehouseMapper;

    @Autowired
    private WmsWarehouseAreaMapper wmsWarehouseAreaMapper;

    @Autowired
    private MesProductionCompletionMapper mesProductionCompletionMapper;

    @Autowired
    private ScmPurchaseArrivalMapper scmPurchaseArrivalMapper;

    @Autowired
    private ScmSaleReturnMapper scmSaleReturnMapper;

    @Autowired
    private WmsMaterialMapper wmsMaterialMapper;

    @Autowired
    private WmsMaterialInventoryMapper wmsMaterialInventoryMapper;

    @Autowired
    private WmsInventoryDetailsMapper wmsInventoryDetailsMapper;

    @Autowired
    private IWmsMaterialInventoryService wmsMaterialInventoryService;


    /**
     * 查询智能仓储WMS-入库申请
     *
     * @param id 智能仓储WMS-入库申请主键
     * @return 智能仓储WMS-入库申请
     */
    @Override
    public WmsWarehousingApplicationVo selectWmsWarehousingApplicationById(Long id)
    {
        WmsWarehousingApplicationVo wmsWarehousingApplicationVo = wmsWarehousingApplicationMapper.selectWmsWarehousingApplicationById(id);
        for (WmsWarehousingApplicationDetails details :wmsWarehousingApplicationVo.getWmsWarehousingApplicationDetailsList()) {
            // 遍历指定仓库中的库区和库位列表，用于前端查询是数据的回显
            details.setWmsWarehouseAreaList(wmsWarehouseMapper.selectWmsWarehouseById(details.getWarehouseId()).getWmsWarehouseAreaList());
            details.setWmsWarehouseSeatList(wmsWarehouseAreaMapper.selectWmsWarehouseAreaById(details.getWarehouseAreaId()).getWmsWarehouseSeatList());
            // 获取物料信息
            details.setMaterialName(wmsMaterialMapper.selectWmsMaterialById(details.getMaterialId()).getMaterialName());
            details.setMaterialCode(wmsMaterialMapper.selectWmsMaterialById(details.getMaterialId()).getMaterialCode());
            details.setMaterialPrice(wmsMaterialMapper.selectWmsMaterialById(details.getMaterialId()).getMaterialPrice());
            details.setMaterialUnit(wmsMaterialMapper.selectWmsMaterialById(details.getMaterialId()).getMaterialUnit());
            details.setMaterialSpecification(wmsMaterialMapper.selectWmsMaterialById(details.getMaterialId()).getMaterialSpecifications());
            details.setMaterialModel(wmsMaterialMapper.selectWmsMaterialById(details.getMaterialId()).getMaterialModel());
        }
        // 获取关联单据号和合同编号
        getAssociationDocumentNo(wmsWarehousingApplicationVo);
        return wmsWarehousingApplicationVo;
    }

    /**
     * 查询智能仓储WMS-入库申请列表
     *
     * @param wmsWarehousingApplicationVo 智能仓储WMS-入库申请
     * @return 智能仓储WMS-入库申请
     */
    @Override
    public List<WmsWarehousingApplicationVo> selectWmsWarehousingApplicationList(WmsWarehousingApplicationVo wmsWarehousingApplicationVo)
    {
        List<WmsWarehousingApplicationVo> list = wmsWarehousingApplicationMapper.selectWmsWarehousingApplicationList(wmsWarehousingApplicationVo);
        // 遍历列表
        list.stream().forEach(item->{
            // 调用获取关联单据号方法
            getAssociationDocumentNo(item);
        });
        return list;
    }

    private void getAssociationDocumentNo(WmsWarehousingApplicationVo wmsWarehousingApplicationVo) {
        //生产入库
        if(wmsWarehousingApplicationVo.getBusinessType() == 1) {
            //获取生产完工单号
            MesProductionCompletionVo completionVo = mesProductionCompletionMapper.selectMesProductionCompletionById(wmsWarehousingApplicationVo.getDocumentNoId());
            if(completionVo != null) {
                wmsWarehousingApplicationVo.setAssociationDocumentNo(completionVo.getOddNumbers());
            }
        }
        //采购入库
        if(wmsWarehousingApplicationVo.getBusinessType() == 2) {
            ScmPurchaseArrival arrive = scmPurchaseArrivalMapper.getById(wmsWarehousingApplicationVo.getDocumentNoId());
            if(arrive != null) {
                wmsWarehousingApplicationVo.setAssociationDocumentNo(arrive.getDeliveryNumber());
                wmsWarehousingApplicationVo.setContractNo(arrive.getPurchasingContractNo());
            }
        }
        //退货入库
        if(wmsWarehousingApplicationVo.getBusinessType() == 3) {
            ScmSaleReturn saleReturn = scmSaleReturnMapper.getById(wmsWarehousingApplicationVo.getDocumentNoId());
            if(saleReturn != null) {
                wmsWarehousingApplicationVo.setAssociationDocumentNo(saleReturn.getReturnNo());
                wmsWarehousingApplicationVo.setContractNo(saleReturn.getContractNo());
            }
        }
    }
    /**
     * 新增智能仓储WMS-入库申请
     *
     * @param wmsWarehousingApplicationVo 智能仓储WMS-入库申请
     * @return 结果
     */
    @Transactional
    @Override
    public int insertWmsWarehousingApplication(WmsWarehousingApplicationVo wmsWarehousingApplicationVo)
    {
        wmsWarehousingApplicationVo.setDocumentNo(generateNumber("RKSQ"));
        // 入库状态: 0未入库1已入库
        wmsWarehousingApplicationVo.setDocumentStatus(Long.parseLong("0"));
        // 申请类型：1入库单2出库单
        wmsWarehousingApplicationVo.setApplicationType(Long.parseLong("1"));
        wmsWarehousingApplicationVo.setApplicant(SecurityUtils.getLoginUser().getUserId());
        // 更新关联单状态
        updateAssociationStatus(wmsWarehousingApplicationVo.getBusinessType(),wmsWarehousingApplicationVo.getDocumentNoId(),Long.parseLong("1"));
        int rows = wmsWarehousingApplicationMapper.insertWmsWarehousingApplication(wmsWarehousingApplicationVo);
        insertWmsWarehousingApplicationDetails(wmsWarehousingApplicationVo);
        return rows;
    }
    /**
     * 更新关联单状态
     */
    public void updateAssociationStatus(Long businessType, Long documentNoId, Long status){
        // 更新生产完工单
        if (businessType == 1) {
            MesProductionCompletionVo completionVo = mesProductionCompletionMapper.selectMesProductionCompletionById(documentNoId);
            MesProductionCompletion mesProductionCompletion = new MesProductionCompletion();
            if(completionVo != null) {
                mesProductionCompletion.setId(completionVo.getId());
                mesProductionCompletion.setStatus(Integer.parseInt(String.valueOf(status)));
                mesProductionCompletionMapper.updateMesProductionCompletion(mesProductionCompletion);
            }
        }
        // 更新采购到货单
        if (businessType == 2) {
            ScmPurchaseArrival arrive = scmPurchaseArrivalMapper.getById(documentNoId);
            if (arrive != null) {
                arrive.setStatus(Math.toIntExact(status));
                scmPurchaseArrivalMapper.edit(arrive);
            }
        }
        //更新销售退货单
        if (businessType == 3) {
            ScmSaleReturn saleReturn = scmSaleReturnMapper.getById(documentNoId);
            if (saleReturn != null) {
                saleReturn.setStatus(String.valueOf(status));
                scmSaleReturnMapper.edit(saleReturn);
            }
        }
    }

    public String generateNumber(String number){
        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        return number+format.format(date);
    }

    /**
     * 修改智能仓储WMS-入库申请
     *
     * @param WmsWarehousingApplicationVo 智能仓储WMS-入库申请
     * @return 结果
     */
    @Transactional
    @Override
    public int updateWmsWarehousingApplication(WmsWarehousingApplicationVo WmsWarehousingApplicationVo)
    {
        if (WmsWarehousingApplicationVo.getApprovedStatus() == null) {
            wmsWarehousingApplicationMapper.deleteWmsWarehousingApplicationDetailsByWarehousingApplicationId(WmsWarehousingApplicationVo.getId());
            insertWmsWarehousingApplicationDetails(WmsWarehousingApplicationVo);
        }
        return wmsWarehousingApplicationMapper.updateWmsWarehousingApplication(WmsWarehousingApplicationVo);
    }

    /**
     * 批量删除智能仓储WMS-入库申请
     *
     * @param ids 需要删除的智能仓储WMS-入库申请主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteWmsWarehousingApplicationByIds(Long[] ids)
    {
        for (Long id : ids) {
            WmsWarehousingApplicationVo applicationVo = wmsWarehousingApplicationMapper.selectWmsWarehousingApplicationById(id);

            if (applicationVo.getBusinessType() == 1) {
                // 更新完工单状态为检验合格
                updateAssociationStatus(applicationVo.getBusinessType(), applicationVo.getDocumentNoId(), Long.parseLong("3"));
            }else {
                //更新关联单据状态为未入库
                updateAssociationStatus(applicationVo.getBusinessType(), applicationVo.getDocumentNoId(), Long.parseLong("0"));
            }
        }
        wmsWarehousingApplicationMapper.deleteWmsWarehousingApplicationDetailsByWarehousingApplicationIds(ids);
        return wmsWarehousingApplicationMapper.deleteWmsWarehousingApplicationByIds(ids);
    }

    /**
     * 删除智能仓储WMS-入库申请信息
     *
     * @param id 智能仓储WMS-入库申请主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteWmsWarehousingApplicationById(Long id)
    {
        WmsWarehousingApplicationVo applicationVo = wmsWarehousingApplicationMapper.selectWmsWarehousingApplicationById(id);
        if (applicationVo.getBusinessType() == 1) {
            // 更新完工单状态为检验合格
            updateAssociationStatus(applicationVo.getBusinessType(), applicationVo.getDocumentNoId(), Long.parseLong("3"));
        }else {
            //更新关联单据状态为未入库
            updateAssociationStatus(applicationVo.getBusinessType(), applicationVo.getDocumentNoId(), Long.parseLong("0"));
        }
        wmsWarehousingApplicationMapper.deleteWmsWarehousingApplicationDetailsByWarehousingApplicationId(id);
        return wmsWarehousingApplicationMapper.deleteWmsWarehousingApplicationById(id);
    }

    /**
     * 新增智能仓储WMS-入库申请明细信息
     *
     * @param wmsWarehousingApplicationVo 智能仓储WMS-入库申请对象
     */
    public void insertWmsWarehousingApplicationDetails(WmsWarehousingApplicationVo wmsWarehousingApplicationVo)
    {
        List<WmsWarehousingApplicationDetails> wmsWarehousingApplicationDetailsList = wmsWarehousingApplicationVo.getWmsWarehousingApplicationDetailsList();
        Long id = wmsWarehousingApplicationVo.getId();
        if (StringUtils.isNotNull(wmsWarehousingApplicationDetailsList))
        {
            List<WmsWarehousingApplicationDetails> list = new ArrayList<WmsWarehousingApplicationDetails>();
            for (WmsWarehousingApplicationDetails wmsWarehousingApplicationDetails : wmsWarehousingApplicationDetailsList)
            {
                wmsWarehousingApplicationDetails.setWarehousingApplicationId(id);
                list.add(wmsWarehousingApplicationDetails);
            }
            if (list.size() > 0)
            {
                wmsWarehousingApplicationMapper.batchWmsWarehousingApplicationDetails(list);
            }
        }
    }

    @Transactional
    @Override
    public void executeWarehousing(Long id) {
        WmsWarehousingApplicationDetails details = new WmsWarehousingApplicationDetails();
        details.setWarehousingApplicationId(id);
        List<WmsWarehousingApplicationDetails> detailList = wmsWarehousingApplicationDetailsMapper
                .selectWmsWarehousingApplicationDetailsList(details);
        detailList.stream().forEach(detail -> {
            Long warehouseId = detail.getWarehouseId();
            Long materialId = detail.getMaterialId();
            // 计算增加的库存
            double in = detail.getArrivalNum() == null ? 0 : detail.getArrivalNum();
            double receive = detail.getReceiptNum() == null ? 0 : detail.getReceiptNum();
            double increase = Math.min(receive, in);
            // 检查入库目标仓库中是否包含该物料
            WmsMaterialInventoryVo wmsMaterialInventoryVo = new WmsMaterialInventoryVo();
            wmsMaterialInventoryVo.setWarehouseId(warehouseId);
            wmsMaterialInventoryVo.setMaterialId(materialId);
            List<WmsMaterialInventoryVo> wmiVoList = wmsMaterialInventoryMapper.selectWmsMaterialInventoryList(wmsMaterialInventoryVo);
            if (wmiVoList != null && !wmiVoList.isEmpty()) {
                WmsMaterialInventoryVo wmiVo = wmiVoList.get(0);
                WmsInventoryDetailsVo wiDetailsVo = new WmsInventoryDetailsVo();
                wiDetailsVo.setWarehouseAreaId(detail.getWarehouseAreaId());
                wiDetailsVo.setWarehouseSeatId(detail.getWarehouseSeatId());
                wiDetailsVo.setBatchNumber(detail.getBatchNumber());
                wiDetailsVo.setMaterialId(detail.getMaterialId());
                List<WmsInventoryDetailsVo> whmDetailList = wmsInventoryDetailsMapper
                        .selectWmsInventoryDetailsList(wiDetailsVo);
                if (whmDetailList != null && !whmDetailList.isEmpty()) {
                    // 修改明细库存
                    WmsInventoryDetailsVo wmsInventoryDetailsVo = whmDetailList.get(0);
                    double inventory = wmsInventoryDetailsVo.getExistingInventory() == null ? 0 : wmsInventoryDetailsVo.getExistingInventory();
                    wmsInventoryDetailsVo.setExistingInventory(inventory + increase);
                    wmsInventoryDetailsMapper.updateWmsInventoryDetails(wmsInventoryDetailsVo);
                } else {
                    // 新增库存明细
                    insertInventoryDetails(wmiVo,detail);
                }
                // 更新仓库总库存
                wmsMaterialInventoryService.updateMaterialTotalInventory(wmiVo.getId());
            } else {
                // 物料库存
                WmsMaterialInventoryVo wmInventoryVo = new WmsMaterialInventoryVo();
                wmInventoryVo.setWarehouseId(warehouseId);
                wmInventoryVo.setMaterialId(materialId);
                // 新增物料库存
                wmsMaterialInventoryMapper.insertWmsMaterialInventory(wmInventoryVo);
                insertInventoryDetails(wmInventoryVo,detail);
                // 更新仓库总库存
                wmsMaterialInventoryService.updateMaterialTotalInventory(wmInventoryVo.getId());
            }
        });
        // 更新入库状态
        WmsWarehousingApplicationVo warehousingApplicationVo = wmsWarehousingApplicationMapper.selectWmsWarehousingApplicationById(id);
        // 单据状态 0未入库1已入库
        warehousingApplicationVo.setDocumentStatus(Long.parseLong("1"));
        wmsWarehousingApplicationMapper.updateWmsWarehousingApplication(warehousingApplicationVo);
        // 更新关联业务单据状态为已入库
        updateAssociationStatus(warehousingApplicationVo.getBusinessType(), warehousingApplicationVo.getDocumentNoId(), Long.parseLong("2"));
    }

    /**
     * 入库-新增物料库存明细
     */
    private void insertInventoryDetails(WmsMaterialInventoryVo inventoryVo,WmsWarehousingApplicationDetails applicationDetails){
        // 物料库存明细
        WmsInventoryDetailsVo wmsInventoryDetailsVo = new WmsInventoryDetailsVo();
        wmsInventoryDetailsVo.setInventoryId(inventoryVo.getId());
        wmsInventoryDetailsVo.setWarehouseAreaId(applicationDetails.getWarehouseAreaId());
        wmsInventoryDetailsVo.setWarehouseSeatId(applicationDetails.getWarehouseSeatId());
        wmsInventoryDetailsVo.setMaterialId(applicationDetails.getMaterialId());
        wmsInventoryDetailsVo.setManufactureDate(applicationDetails.getManufactureDate());
        wmsInventoryDetailsVo.setManufacturer(applicationDetails.getProductionUnit());
        wmsInventoryDetailsVo.setBatchNumber(applicationDetails.getBatchNumber());
        wmsInventoryDetailsVo.setExistingInventory(applicationDetails.getReceiptNum());
        // 新增物料库存明细
        wmsInventoryDetailsMapper.insertWmsInventoryDetails(wmsInventoryDetailsVo);
    }
}
